﻿using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.ServiceLocation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Songhay.Extensions;
using Songhay.Models;
using System.Linq;

namespace Songhay.BiggestBox.Desktop.Tests
{
    using Microsoft.Practices.Prism.Mvvm;
    using Portable.Shared.Services;

    /// <summary>
    /// Tests for <see cref="ClientBootstrapper"/>
    /// </summary>
    [TestClass]
    public class ClientBootstrapperTest
    {
        /// <summary>
        /// Initializes the test.
        /// </summary>
        [TestInitialize]
        public void InitializeTest()
        {
            this.TestContext.RemovePreviousTestResults();

            _bootsrapper = new ClientBootstrapper();
            _bootsrapper.Run();
        }

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        /// <summary>
        /// Client bootstrapper tests: should get exported views by contract names.
        /// </summary>
        [TestMethod]
        [TestProperty("contractNames", "PackedXamlView,SvgFontsView")]
        public void ShouldGetExportedViewsByContractNames()
        {
            var contractNames = this.TestContext.Properties["contractNames"].ToString().Split(',');

            var container = this._bootsrapper.GetCompositionContainer();
            Assert.IsNotNull(container, "The expected MEF container is not here.");

            contractNames.ForEachInEnumerable(i =>
            {
                var view = container.GetExportedValue<IView>(i);
                Assert.IsNotNull(view, "The expected View is not here.");
                this.TestContext.WriteLine("view: {0}", view);
            });
        }

        /// <summary>
        /// Client bootstrapper tests: should get rest model context service.
        /// </summary>
        [TestMethod]
        public void ShouldGetIRestModelContextService()
        {
            var restModelContextService = ServiceLocator.Current.GetInstance<IRestModelContextService>();

            Assert.IsNotNull(restModelContextService, "The expected Prism service is not here.");
        }

        /// <summary>
        /// Client bootstrapper tests: should get module instances.
        /// </summary>
        [TestMethod]
        public void ShouldGetIModuleInstances()
        {
            var instances = ServiceLocator.Current.GetAllInstances<IModule>();
            Assert.IsNotNull(instances, "The expected instances are not here.");
            //FUNKYKB: note that MefServiceLocatorAdapter uses IEnumerable<Lazy<object, object>> to implement GetAllInstances().

            var models = instances.OfType<DisplayItemModel>().OrderBy(i => i.DisplayText);
            Assert.IsTrue(models.Any(), "The expected models are not here.");

            models.ForEachInEnumerable(i => this.TestContext.WriteLine("item: {0}", i));
        }

        /// <summary>
        /// Client bootstrapper tests: should get view instances.
        /// </summary>
        [TestMethod]
        [TestProperty("contractNames", "PackedXamlView,SvgFontsView")]
        public void ShouldGetViewInstances()
        {
            var contractNames = this.TestContext.Properties["contractNames"].ToString().Split(',');

            contractNames.ForEachInEnumerable(i =>
            {
                var instance = ServiceLocator.Current.GetInstance<IView>(i);
                Assert.IsNotNull(instance, "The expected instance is not here.");
                this.TestContext.WriteLine("view: {0}", instance);
            });
        }

        ClientBootstrapper _bootsrapper;
    }
}
